﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.Mvc;
using System.Globalization;

namespace MvcImproved.Generic.Controls
{
	public class TextBox<TDataItem, TMemberValue> : GenericInputControl<TDataItem, TMemberValue>, ITextControl
	{
		public TextBox(Func<TDataItem, TMemberValue> valueMember)
			: base(valueMember, "text")
		{
		}

		string _Text;
		public string Text
		{
			get
			{
				string attemptedValue = (string)GetModelStateValue(Name, typeof(string));

				if (attemptedValue == null)
				{
					TMemberValue value = ValueMemberLambda(DataValue);
					return (value != null) ? value.ToString() : _Text;
				}
				else
					return attemptedValue;
			}
			set
			{
				_Text = value;
			}
		}

		public int MaxLength = -1;

		public bool MultipleRows = false;

		protected override void Render(HtmlTextWriter writer)
		{
			if (!MultipleRows)
			{
				base.Render(writer);
				return;
			}

			if (!DesignMode && String.IsNullOrEmpty(Name))
			{
				throw new InvalidOperationException("Name Required");
			}

			SortedDictionary<string, string> attrs = new SortedDictionary<string, string>();

			foreach (KeyValuePair<string, string> attribute in Attributes)
			{
				attrs.Add(attribute.Key, attribute.Value);
			}

			attrs.Add("name", Name);
			if (!String.IsNullOrEmpty(ID))
			{
				attrs.Add("id", ID);
			}

			ControlSpecificRender(writer, attrs);

			if (!DesignMode)
			{
				// If there are any errors for a named field, we add the CSS attribute.
				ModelState modelState = GetModelState();
				if ((modelState != null) && (modelState.Errors.Count > 0))
				{
					string currentValue;

					if (attrs.TryGetValue("class", out currentValue))
					{
						attrs["class"] = HtmlHelper.ValidationInputCssClassName + " " + currentValue;
					}
					else
					{
						attrs["class"] = HtmlHelper.ValidationInputCssClassName;
					}
				}
			}

			foreach (KeyValuePair<string, string> attribute in attrs)
			{
				writer.AddAttribute(attribute.Key, Convert.ToString(attribute.Value, CultureInfo.CurrentCulture));
			}

			writer.RenderBeginTag(HtmlTextWriterTag.Textarea);

			writer.Write(Text);

			writer.RenderEndTag();
		}

		protected override void ControlSpecificRender(HtmlTextWriter writer, SortedDictionary<string, string> attrs)
		{
			if (!DesignMode)
			{
				attrs.Add("value", Text);

				if (MaxLength != -1)
					attrs.Add("maxlength", MaxLength.ToString());
			}
		}
	}
	
	// Non-generic version of the control that's used in the actual markup
	[ControlBuilder(typeof(GenericControlBuilder))]
	[GenericControlType(typeof(TextBox<,>), MemberValue = "ValueMember", GenericParameters = "ModelType")]
	public class TextBox : TextBox<object, object>
	{
		public TextBox()
			: base(null)
		{ }

		public string ModelType
		{
			get;
			set;
		}
	}
}
